﻿using Furion;
using Furion.EventBus;
using Furion.FriendlyException;
using Furion.JsonSerialization;
using FurionApi.Demo.Core.Const;
using FurionApi.Demo.Core.EventSubscriber.Dto;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace FurionApi.Demo.Web.Core.Middleware
{
    public class CustomerExceptionMiddleware
    {/// <summary>
     /// 委托
     /// </summary>
        private readonly RequestDelegate _next;
        private readonly IEventPublisher _eventPublisher;
        private readonly ILogger<CustomerExceptionMiddleware> _logger;

        public CustomerExceptionMiddleware(RequestDelegate next, IEventPublisher eventPublisher, ILogger<CustomerExceptionMiddleware> logger)
        {
            this._next = next;
            this._eventPublisher = eventPublisher;
            this._logger = logger;
        }

        public async Task Invoke(HttpContext context)
        {
            try
            {
                await _next(context);
            }
            catch (Exception ex)
            {
                

                context.Response.ContentType = "application/json";

                var title = "An error occured: " + ex.Message;
                var details = ex.ToString();


                var problem = new Util.XnRestfulResult<object>
                {
                    Code = 500,
                    Success = false,
                    Data = details,
                    Message = title,
                    Extras = null,
                    Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
                };


                var stream = context.Response.Body;
                await JsonSerializer.SerializeAsync(stream, problem);

                var userContext = App.User;
                await _eventPublisher.PublishAsync(new ChannelEventSource("Create:ExLog", new SysLogEx
                {
                    Account = userContext?.FindFirstValue(ClaimConst.CLAINM_ACCOUNT),
                    Name = userContext?.FindFirstValue(ClaimConst.CLAINM_NAME),
                    ClassName = ex.TargetSite.DeclaringType?.FullName,
                    MethodName = ex.TargetSite.Name,
                    ExceptionName = ex.Message,
                    ExceptionMsg = ex.Message,
                    ExceptionSource = ex.Source,
                    StackTrace = ex.StackTrace,
                    ParamsObj = ex.TargetSite.GetParameters().ToString(),
                    ExceptionTime = DateTimeOffset.Now
                }));
                //await _eventPublisher.PublishAsync(new ChannelEventSource("Create:ExLog",
                //    new SysLogEx
                //    {
                //        Account = userContext?.FindFirstValue(ClaimConst.CLAINM_ACCOUNT),
                //        Name = userContext?.FindFirstValue(ClaimConst.CLAINM_NAME),
                //        ClassName = context.Exception.TargetSite.DeclaringType?.FullName,
                //        MethodName = context.Exception.TargetSite.Name,
                //        ExceptionName = context.Exception.Message,
                //        ExceptionMsg = context.Exception.Message,
                //        ExceptionSource = context.Exception.Source,
                //        StackTrace = context.Exception.StackTrace,
                //        ParamsObj = context.Exception.TargetSite.GetParameters().ToString(),
                //        ExceptionTime = DateTimeOffset.Now
                //    }));

                // 写日志文件
                _logger.LogError(ex.ToString());
            }
        }
    }
}
